﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using System.Threading;
using WHLRDF.Log;

namespace WHLRDF
{
    /// <summary>
    /// 任务 启动类
    /// </summary>
    public class TaskHelper
    {
        private List<TaskModel> _taskModels =null;
     
        private readonly static object locked = new object();
        private static TaskHelper _instance;
        public static TaskHelper Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (locked)
                    {
                        if (_instance == null)
                        {
                            _instance = new TaskHelper();
                        }
                    }
                }
                return _instance;
            }
        }
        public TaskHelper() {
            _taskModels = new List<TaskModel>();
        }

        private ITaskService _taskService = null;
        public ITaskService TaskService
        {
            get {
                if (_taskService == null)
                {
                    _taskService = AppHttpContext.GetSerivce<ITaskService>();
                }
                return _taskService;
            }
        }
        /// <summary>
        /// 启动新的任务
        /// </summary>
        /// <param name="title">线程标题</param>
        /// <param name="userno">用户编号</param>
        /// <param name="func">委托</param>
        /// <param name="taskNo">任务唯一标识</param>
        /// <param name="isWriteDbLog">是否写入Db</param>
        public TaskModel TaskStart(string title,string userno,Func<TaskModel, bool> func,string taskNo="",bool isWriteDbLog=true)
        {
            //string strError = "";
            var taskModel = new TaskModel();
            taskModel.TaskName = title;
            taskModel.TaskId = MyGenerateHelper.GenerateOrder(5);
            taskModel.TaskToken= new CancellationTokenSource();
            taskModel.TaskNo = taskNo;
            taskModel.UserNo = userno;
            taskModel.CurrentTask= Task.Factory.StartNew(() => {
                taskModel.StartDate = DateTime.Now;
                taskModel.IsOpen = true;
                int milliStart = Environment.TickCount;
                taskModel.ExcuteFunc = func;
                try
                {
                    taskModel.IsSuccess = taskModel.ExcuteFunc(taskModel);
                    if (taskModel.IsSuccess&&string.IsNullOrWhiteSpace(taskModel.Message))
                    {
                        taskModel.Message = "成功";
                    }
                }
                catch (Exception ex)
                {
                    taskModel.Message = taskModel.Message+ ex.Message+ex.StackTrace;
                    taskModel.IsSuccess = false;
                    taskModel.IsOpen = false;
                }
                if (taskModel.TaskToken.Token.IsCancellationRequested)
                {
                    taskModel.IsSuccess = false;
                    taskModel.Message = "任务被强行终止";
                }
                int milliEnd = Environment.TickCount;
                taskModel.EndDate = DateTime.Now;
                taskModel.ExcuteTime=  TimeSpan.FromMilliseconds(milliEnd - milliStart).TotalMilliseconds;
                taskModel.IsOpen = false;
                //_taskModels.Remove(taskModel);
               // TaskService.InsertTask(taskModel, ref strError);
                LogHelper.TaskInfo(taskModel);
                SendResultMessage(taskModel.UserNo, taskModel.UserToken, title + taskModel.Message);

            }, TaskCreationOptions.LongRunning);
            _taskModels.Add(taskModel);
         
            //TaskService.InsertTask(taskModel,ref strError);
            return taskModel;


        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="taskId"></param>
        /// <returns></returns>
        public bool Stop(string taskId,ref string strError)
        {
            if (string.IsNullOrWhiteSpace(taskId))
            {
                strError = "请输入需要终止的任务id";
                return false;
            }
            var task= _taskModels.Where(x => x.TaskId == taskId).FirstOrDefault();
            if (task == null|| !task.IsOpen)
            {
                strError = "任务不存在或者已关闭";
                return false;
            }
            
            task.TaskToken.Cancel();
            task.Message = "任务被强行终止";
            //TaskService.InsertTask(task, ref strError);
            // LogHelper.Info(task.TaskName, task.ToJson());
            //TaskModels.Remove(task);
            return true;
        }

        /// <summary>
        /// 查询Task 任务状态
        /// </summary>
        /// <param name="taskId">任务id</param>
        /// <param name="strError">是否错误</param>
        /// <returns></returns>
        public TaskModel GetById(string taskId,ref string strError)
        {
            if (string.IsNullOrWhiteSpace(taskId))
            {
                strError = "请输入需要终止的任务id";
                return null;
            }
            var task = _taskModels.Where(x => x.TaskId == taskId).FirstOrDefault();
            if (task == null || !task.IsOpen)
            {
                strError = "任务不存在或者已关闭";
            }
            return task;
        }

        /// <summary>
        /// 移除任务
        /// </summary>
        /// <param name="taskId"></param>
        /// <param name="strError"></param>
        /// <returns></returns>
        public bool Remove(string taskId, ref string strError)
        {
            if (string.IsNullOrWhiteSpace(taskId))
            {
                strError = "请输入需要终止的任务id";
                return false;
            }
            var task = _taskModels.Where(x => x.TaskId == taskId).FirstOrDefault();
            if (task != null &&task.IsOpen)
            {
                strError = "任务未关闭或者取消无法移除";
                return false;
            }
            _taskModels.Remove(task);
            return true;
        }

        /// <summary>
        /// 获取所有任务
        /// </summary>
        public List<TaskModel> GetTaskAll {
            get {
                return _taskModels;
            }
        }

        /// <summary>
        /// 查询所有任务
        /// </summary>
        /// <param name="ligerGrid"></param>
        /// <returns></returns>
        public LigerGrid ForGrid(LigerGrid ligerGrid)
        {
            if (_taskModels != null && _taskModels.Count > 0)
            {
                ligerGrid.Total = _taskModels.Count;
                var resultTask = _taskModels;
                string taskName = ligerGrid.GetValue("TaskName");
                string isOpen = ligerGrid.GetValue("IsOpen");
                if (!string.IsNullOrWhiteSpace(taskName))
                {
                    resultTask= resultTask.Where(x => x.TaskName.Contains(taskName)).ToList();
                }
                if (!string.IsNullOrWhiteSpace(isOpen))
                {
                    resultTask = resultTask.Where(x => x.IsOpen==ConvertHelper.ObjToBool(isOpen)).ToList();
                }
                var result = resultTask.Skip((ligerGrid.pageIndex - 1) * ligerGrid.pageSize).Take(ligerGrid.pageSize);
                ligerGrid.records = result.Count();
            }
            return ligerGrid;
        }
        /// <summary>
        /// 发送任务结果
        /// </summary>
        /// <param name="userno"></param>
        /// <param name="userToken"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool SendResultMessage(string userno, string userToken, string message)
        {
            var socketMessage = new 
            {
                SenderId = "Service",
                SenderName = "系统",
                ReceiverId = userno,
                Content = message
            };
            string strResult = "";
            return SendHttpHelper.SendWebClientAsync(ApplicationEnvironments.Site.SendMessageUrl, socketMessage.ToJson(), userToken, ref strResult);

        }
    
    }

    /// <summary>
    /// 任务
    /// </summary>
    public class TaskModel
    {
        /// <summary>
        /// 任务Id
        /// </summary>
        public string TaskId { get; set; }

        /// <summary>
        /// 任务编码（无效）
        /// </summary>
        public string TaskNo { get; set; }
        /// <summary>
        /// 任务名称
        /// </summary>
        public string TaskName { get; set; }

        /// <summary>
        /// 执行时间
        /// </summary>
        public double ExcuteTime { get; set; }
        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime StartDate { get; set; }

        /// <summary>
        /// 结束时间
        /// </summary>
        public DateTime EndDate { get; set; }

        public bool IsOpen { get; set; }
        [JsonIgnore]
        /// <summary>
        /// 执行方法 返回true or false
        /// </summary>
        public Func<TaskModel, bool> ExcuteFunc { get; set; }

        [JsonIgnore]
        public Task CurrentTask { get; set; }

        [JsonIgnore]
        /// <summary>
        /// 取消标志
        /// </summary>
        public CancellationTokenSource TaskToken { get; set; }

        /// <summary>
        /// 是否执行成功
        /// </summary>
        public bool IsSuccess { get; set; }

        /// <summary>
        /// 输出消息
        /// </summary>
        public string Message { get; set; }

        public string UserNo { get; set; }

        public string UserToken { get; set; }
    }
}
